home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Add-Ons / After Dark / Joe Judge / Sphere ƒ / module.c < prev    next >
Encoding:
Text File  |  1994-11-26  |  10.5 KB  |  414 lines  |  [TEXT/KAHL]

  1.  
  2.  
  3. // I'm rethinking the sound thing ...
  4. // what if I don't have a set of various sounds ?
  5. // instead, take one sound - different pitches ... and let the program 
  6. // play the various pitches randomly (== music? I think not)
  7. // later I can refine the randomness to play ping noise
  8. // so there is *some* rhyme and reason to the random notes :)
  9.  
  10. #include "GraphicsModule_Types.h"
  11. #include "Sounds.h"
  12.  
  13.  
  14. // these are the functs that need defined ...
  15. OSErr DoInitialize(Handle *storage, RgnHandle blankRgn, GMParamBlockPtr params);
  16. OSErr DoClose(Handle storage, RgnHandle blankRgn, GMParamBlockPtr params);
  17. OSErr DoBlank(Handle storage, RgnHandle blankRgn, GMParamBlockPtr params);
  18. OSErr DoDrawFrame(Handle storage, RgnHandle blankRgn, GMParamBlockPtr params);
  19. OSErr DoSetUp(RgnHandle blankRgn, short message, GMParamBlockPtr params);
  20. // these must be defined also
  21. OSErr DoSelected(RgnHandle blankRgn, short message, GMParamBlockPtr params);
  22. OSErr DoAboutBox(RgnHandle blankRgn, short message, GMParamBlockPtr params);
  23.  
  24. short gTheMonitor;
  25.  
  26. #define FlipACoin()        (RangedRdm(0, 100) > 50)
  27.  
  28. SoundInfoHandle gSndInfoHandle;
  29. #define BASE_NOTE_ID 128
  30. #define BASE_BEAT_ID 1000
  31.  
  32. #define MAX_NOTES 9
  33. #define MAX_BEATS 2
  34.  
  35. Handle gNotes[MAX_NOTES];        // how many?  E f G a B c D e F == 9 ? plus silence!
  36. Handle gBeats[MAX_BEATS];
  37.  
  38. Boolean gDoSound = FALSE;
  39.  
  40. short gCurrentNote = 0;
  41. long gNotesPlayed = 0;
  42.  
  43. long gNoteStop = 0;
  44.  
  45. unsigned short RangedRdm( unsigned short min, unsigned short max );
  46.  
  47. short gState, gDimness;
  48. enum {
  49.     DIMMING,
  50.     DONE,
  51.     STOP
  52. };
  53.  
  54. //////////////////////////////////////////////////////////////////////////////////////
  55. // this is the first funct called by AD ... we need to allocate and initialize here
  56. OSErr
  57. DoInitialize(Handle *storage, RgnHandle blankRgn, GMParamBlockPtr params) {
  58. void initsphere(int screen, Rect *theRect);
  59.  
  60.     gDimness = 255;
  61.     
  62.     for (gTheMonitor=0; 
  63.             (gTheMonitor < params->monitors->monitorCount && gTheMonitor < 4); 
  64.                 gTheMonitor++)
  65.         initsphere(gTheMonitor, 
  66.                 &(params->monitors->monitorList[gTheMonitor].bounds) );
  67.  
  68.     GetDateTime((unsigned long *) ¶ms->qdGlobalsCopy->qdRandSeed);
  69.  
  70. #ifdef DO_SOUND
  71.     if (params->systemConfig & SoundAvailable) {
  72.         short i;
  73.         
  74.         gDoSound = TRUE;
  75.         for (i = 0; i<MAX_NOTES; i++)
  76.             gNotes[i] = GetResource('snd ', BASE_NOTE_ID + i);
  77.         for (i=0; i<MAX_BEATS; i++)
  78.             gBeats[i] = GetResource('snd ', BASE_BEAT_ID + i);
  79.             
  80.         /* to use the sound functions in AD 2.0u we must pass in "params" */
  81.         gSndInfoHandle = OpenSound(params);
  82.     } else gDoSound = FALSE;
  83. #else
  84.     gDoSound = FALSE;
  85. #endif
  86.  
  87.     gTheMonitor = 0;
  88.     return noErr;
  89. }
  90.  
  91. //////////////////////////////////////////////////////////////////////////////////////
  92. // the screen saver has been awakened! time to ditch the storage and wave goodbye
  93. OSErr 
  94. DoClose(Handle storage, RgnHandle blankRgn, GMParamBlockPtr params) {
  95. short i;
  96.  
  97.     params->brightness = 255;
  98.     
  99.  
  100. #ifdef DO_SOUND
  101.     if (gDoSound ) {
  102.         CloseSound(gSndInfoHandle, params->sndChannel);
  103.         
  104.         for (i=0; i<MAX_NOTES; i++) {
  105.             if (gNotes[i] != NULL )
  106.                 ReleaseResource( gNotes[i] );
  107.         }
  108.         
  109.         for (i=0; i<MAX_BEATS; i++){
  110.             if (gBeats[i] != NULL)
  111.                 ReleaseResource( gBeats[i] );    
  112.         }
  113.         
  114.     }
  115. #endif 
  116.     return noErr;
  117. }
  118.  
  119.  
  120.  
  121. //////////////////////////////////////////////////////////////////////////////////////
  122. // make the screen go black
  123. OSErr
  124. DoBlank(Handle storage, RgnHandle blankRgn, GMParamBlockPtr params) {
  125.  
  126.     if (params->controlValues[0])
  127.         gState = DIMMING;
  128.     else
  129.         gState = STOP;
  130.     return noErr;
  131.  
  132. }
  133.  
  134. //////////////////////////////////////////////////////////////////////////////////////
  135. // this is the workhorse routine. It does the continual screen work to make
  136. // this screen saver what it is.
  137. OSErr 
  138. DoDrawFrame(Handle storage, RgnHandle blankRgn, GMParamBlockPtr params) 
  139. {
  140. void drawsphere(int screen, int screenDepth);
  141. int Dim(void);
  142.  
  143. //// dimming code ...
  144.     if ( gState == DIMMING) {
  145.         params->brightness = Dim();
  146.         if (params->brightness == 0)
  147.             gState = DONE;
  148.         return noErr;
  149.     }
  150.     if ( gState == DONE) {
  151.         FillRgn(blankRgn, params->qdGlobalsCopy->qdBlack);
  152.         params->brightness = 255;
  153.         gState = STOP;
  154.     }
  155. ////
  156.  
  157.     
  158.     if (gTheMonitor >= 4 || gTheMonitor >= params->monitors->monitorCount)
  159.         gTheMonitor = 0;
  160.  
  161. #ifdef DO_SOUND
  162.     // There is a sound ? and we are available to deal with sounds?
  163.     if (gDoSound &&
  164.             (
  165. //                (!SoundBusy(gSndInfoHandle, params->sndChannel)) || 
  166.                 (TickCount() >= gNoteStop)) 
  167.             ) {
  168.  
  169.     gNotesPlayed++;                    // up our count
  170.     
  171.     if ( !(gNotesPlayed % 4)) {    // time for a beat ?
  172.         gCurrentNote = RangedRdm(0, MAX_BEATS-1);
  173.         gNoteStop = TickCount() + 90;
  174.         if (gBeats[ gCurrentNote ] != NULL)
  175.             PlaySound( gSndInfoHandle, params->sndChannel,
  176.                 gBeats[ gCurrentNote ] );
  177.     } else {                            // time for a note now
  178.         
  179.         if (FlipACoin())                // 50/50 chance
  180.             gCurrentNote = gCurrentNote - RangedRdm(1, 2);
  181.         else 
  182.             gCurrentNote = gCurrentNote + RangedRdm(1, 2);
  183.  
  184.         if (gCurrentNote >= MAX_NOTES)    // come down from the top the overflow amt.
  185.             gCurrentNote = (MAX_NOTES-1) - (gCurrentNote - MAX_NOTES);
  186.             
  187.         if (gCurrentNote < 0)            // flip it to be > 0
  188.             gCurrentNote = -gCurrentNote;
  189.  
  190.         // how long of a note?
  191.         if (!(gNotesPlayed % 5))
  192.             gNoteStop = TickCount() + 60;    
  193.         else {
  194.         short minticks, maxticks;
  195.             
  196.             minticks = params->controlValues[1] / 5;
  197.             maxticks = 30 + (params->controlValues[2] / 5);
  198.             gNoteStop = TickCount() + 
  199.                 RangedRdm( minticks, maxticks);
  200.         }
  201.         if ( gNotes[ gCurrentNote ] != NULL )
  202.                 PlaySound( gSndInfoHandle, params->sndChannel, gNotes[ gCurrentNote] );
  203.         }
  204.     }
  205. #endif
  206.     
  207.     
  208.     drawsphere( gTheMonitor, 
  209.             params->monitors->monitorList[gTheMonitor].curDepth);
  210.             
  211.     gTheMonitor++;
  212.     return noErr;
  213. }
  214.  
  215. //////////////////////////////////////////////////////////////////////////////////////
  216. // this is called when they click on something in the control panel
  217. OSErr 
  218. DoSetUp(RgnHandle blankRgn, short message, GMParamBlockPtr params) {
  219.     // button got pushed?? 
  220.     return noErr;
  221. }
  222.  
  223.  
  224.  
  225. OSErr DoSelected(RgnHandle blankRgn, short message, GMParamBlockPtr params) {
  226.     return noErr;
  227. }
  228.  
  229.  
  230.  
  231. OSErr DoAboutBox(RgnHandle blankRgn, short message, GMParamBlockPtr params) {
  232. void initsphere(int screen, Rect *theRect);
  233. Boolean HasColorQD(void);
  234. GrafPtr savePort;
  235. PicHandle    pHandle;
  236. Boolean GetOut = FALSE;
  237. unsigned char thePatterns[6][8] = {
  238.     0x0020, 0x0000, 0x0002, 0x0000,
  239.     0x8010, 0x0220, 0x0108, 0x4004, 
  240.     0x8822, 0x8822, 0x8822, 0x8822, 
  241.     0xAA55, 0xAA55, 0xAA55, 0xAA55, 
  242.     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
  243.     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
  244. };
  245.  
  246.     
  247.     gDoSound = FALSE;
  248.  
  249.     gTheMonitor = 0;
  250.     GetPort( &savePort);
  251.     EraseRect( &savePort->portRect);
  252.  
  253.  
  254.     initsphere(0,  &(savePort->portRect) );
  255.     // can we somehow make a "mask" of text ... so the
  256.     // spheres will not be able to draw over it ...
  257.     // then  - the text will emerge from the image as the
  258.     // spheres draw about
  259.     ForeColor(blackColor);
  260.     BackColor(whiteColor);    
  261.     
  262. // now ... show it all, animate it ... wait for user click
  263.     while (!Button()) {
  264.         if (HasColorQD())
  265.             drawsphere( 0, (*((CGrafPtr)savePort)->portPixMap)->pixelSize );
  266.         else 
  267.             drawsphere(0, 1);
  268.     }
  269.  
  270. // user clicked .. now fade in our message ...
  271.     pHandle = GetPicture( 128 );    // about message in B&W
  272.     if (pHandle) {
  273.         BitMap bm, bm2;
  274.         int width;
  275.         GrafPort gp;
  276.         Boolean DITCHFLAG = FALSE;
  277.  
  278. ////// create an offscreen bitmap (size of the screen window) for the picture
  279.         width = savePort->portRect.right - savePort->portRect.left;
  280.         bm.rowBytes = ((width + 15) / 16) * 2;
  281.         bm.bounds.left = 0;
  282.         bm.bounds.right = width;
  283.         bm.bounds.bottom = savePort->portRect.bottom - savePort->portRect.top;
  284.         bm.bounds.top  = 0;
  285.  
  286. //DebugStr("\pNewPtrClear bm.baseAddr");
  287.  
  288.         bm.baseAddr = NewPtrClear((long)bm.rowBytes * bm.bounds.bottom);
  289.         if (bm.baseAddr != NULL) { 
  290.             short wDiff, hDiff;
  291.             OpenPort( &gp);
  292.             SetPortBits( &bm);
  293.             BackPat( &thePatterns[5][0]);
  294.         
  295.             BlockMove( (Ptr)&bm.bounds, (Ptr)&gp.portRect, sizeof(Rect));
  296.             RectRgn( gp.visRgn, &bm.bounds);
  297.             
  298.             // ok, now draw the picture in that offscreen port ...
  299.             
  300.             wDiff = (bm.bounds.right - bm.bounds.left) -
  301.                 ( (**pHandle).picFrame.right -(**pHandle).picFrame.left);
  302.             hDiff = (bm.bounds.bottom- bm.bounds.top) -
  303.                 ( (**pHandle).picFrame.bottom -(**pHandle).picFrame.top);
  304.             
  305.             // if the offscreen bitmap is larger than the pict bounds, center it
  306.             if ( wDiff > 0 || hDiff > 0 ) {
  307.                 Rect theRect;
  308.                 
  309.                 // FILL ME black
  310.                 BackColor( blackColor);    // black!
  311.                 EraseRect( &bm.bounds);    // clear out those white edges that will come
  312.                 BackColor( whiteColor); // set back to white
  313.                 
  314.                 if (wDiff < 0) wDiff = 0;        // lets not go negative!!!!
  315.                 if (hDiff < 0) hDiff = 0;        // (the pict will slide offscreen!
  316.                 theRect = (**pHandle).picFrame;
  317.                 OffsetRect( &theRect, wDiff/2, hDiff/2);
  318.                 DrawPicture( pHandle, &theRect );
  319.                 
  320.             } else 
  321.                 DrawPicture( pHandle, &bm.bounds); // just blit/scrunch it in
  322.                 
  323.             // OK, bm has the text message picture in it now! whew!
  324.                     
  325. /////////////// dup a bitmap to that one
  326.             BlockMove( &bm, &bm2, sizeof(BitMap) ); // copy the bitmap
  327.  
  328. //DebugStr("\pNewPtrClear bm2.baseAddr");
  329.  
  330.             // but we do need to allocate our own picture area ...
  331.             bm2.baseAddr = NewPtrClear((long)bm.rowBytes * bm.bounds.bottom);
  332.             if (bm2.baseAddr != NULL) {
  333.                 int i;
  334.                 
  335.                 SetPort(&gp);
  336.                 SetPortBits( &bm2);
  337.                 BlockMove( (Ptr)&bm2.bounds, (Ptr)&gp.portRect, sizeof(Rect));
  338.                 RectRgn( gp.visRgn, &bm2.bounds);
  339.  
  340.                 //SetPort( savePort);
  341.                 //ForeColor(blackColor);
  342.                 //PenMode( patXor);
  343.                 
  344.                 for (i = 0; i < 6 && !GetOut; i++) {
  345.                 short x, y;
  346.  
  347.                     SetPort(&gp);
  348.                     SetPortBits( &bm2);
  349.                 
  350.                     // fill the "mask" bitmap, bm2, with a pattern
  351.                     FillRect( &(gp.portRect), &thePatterns[i][0]);
  352.  
  353.                     // copy the image into the main window using the mask
  354.                     CopyMask( 
  355.                         &bm, 
  356.                         &bm2, 
  357.                         &(savePort->portBits),
  358.                         &bm.bounds, 
  359.                         &bm2.bounds, 
  360.                         &savePort->portRect);
  361.  
  362.                 }
  363.             } else DITCHFLAG = TRUE;
  364.         } else DITCHFLAG = TRUE;
  365.         SetPort( savePort);
  366.  
  367. //DebugStr("\pClosing port and disposing ptrs");
  368.     
  369.         // ditch the port
  370.         ClosePort( &gp);
  371.         // ditch the bitmaps
  372.         DisposPtr(bm.baseAddr);
  373.         DisposPtr(bm2.baseAddr);
  374.         
  375.         // didn't happen ... then just draw the picture
  376.         if (DITCHFLAG == TRUE)  
  377.             DrawPicture( pHandle, &(savePort->portRect) );
  378.                 
  379.         ReleaseResource( (Handle)pHandle);
  380.     } else SysBeep(0);
  381.     
  382.     while (!Button() && !GetOut)
  383.         ;
  384.     // ditch events for Darkside to be happy
  385.     FlushEvents( everyEvent, 0);
  386.     
  387.     return noErr;
  388. }
  389.  
  390.  
  391. Boolean
  392. HasColorQD(void) {
  393.     OSErr    err;
  394.     Boolean answer = true;
  395.     long    gestaltResult;
  396.  
  397.     err = Gestalt(gestaltQuickdrawVersion, &gestaltResult);
  398.  
  399.     answer = (err == noErr) && (gestaltResult >= gestalt8BitQD);
  400.     return answer;
  401. }
  402.  
  403.  
  404. int 
  405. Dim(void) {
  406.     gDimness -= 10;
  407.     if (gDimness <= 0) {
  408.         gDimness = 0;
  409.     }        
  410.     return gDimness;
  411. }
  412.  
  413.  
  414.